package com.yangxk.kadmin.web.common.filter;

import com.yangxk.kadmin.web.common.Const;
import com.yangxk.kadmin.web.common.SessionUserHolder;
import com.yangxk.kadmin.web.module.system.po.User;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@WebFilter(filterName = "登录过滤器", urlPatterns = "/*")
public class LoginFilter implements Filter {

    private Set<String> whiteList = new HashSet<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        whiteList.add("/login");
        whiteList.add("/unlogin");
        whiteList.add("/error");
        whiteList.add("/actuator/**");
        whiteList.add("/ureport");
        whiteList.add("/favicon.ico");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        String path = request.getServletPath();

        // 过滤白名单
        if (whiteMatcher(path)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return ;
        }

        User user = (User)request.getSession().getAttribute(Const.SESSION_USER_KEY);
        // 当前用户未登录，转发至/unlogin中抛出异常
        if (user == null) {
            request.getRequestDispatcher("/unlogin").forward(servletRequest, servletResponse);
            return ;
        }

        // 将登录用户信息绑定到当前线程中
        SessionUserHolder.set(user);

        filterChain.doFilter(servletRequest, servletResponse);

        // 从线程中移除当前登录信息
        SessionUserHolder.remove();
    }

    private boolean whiteMatcher(String url) {
        AntPathMatcher matcher = new AntPathMatcher();
        for (String whiteUrl : whiteList) {
            if (matcher.match(whiteUrl, url))
                return true;
        }
        return false;
    }

    @Override
    public void destroy() {

    }

}
